#pragma once

namespace hxc
{

struct _OverlappedCtx : public OVERLAPPED
{
	_OverlappedCtx(const _OverlappedCtx& value);
	_OverlappedCtx(CSocketBase* pObj);
    ~_OverlappedCtx();
	//enum {OPER_NULL= 1, OPER_ACCEPT = 0x10, OPER_CLOSE, OPER_CONN, OPER_DISCONN, OPER_RECV, OPER_SEND};
	enum {BUFFER_MAX_LENGTH = 4 * 1024, BUFFER_MAX_COUNT = 5};
    ULONG_PTR Param;
    int addrlen;
	sockaddr_in RemoteAddr;//short*2+long+BYTE*8
    WSABUF Buffer;
    DECLARE_EVENT(CallBack, CSocketBase, _OverlappedCtx)
};

class _DataPool
{
public:
	void Initialize();
	void Free();
	_OverlappedCtx* GetFreeOverlappedContext(CSocketBase* pObj);
	SOCKET GetFreeTCPSocket();
    SOCKET GetFreeUDPSocket();
	void GetFreeBuffer(char** pArray, USHORT Count);
	void Revert(_OverlappedCtx* Element);
	void RevertTCPSocket(SOCKET Element);
    void RevertUDPSocket(SOCKET Element);
	void Revert(char* Element);
private:
	CRITICAL_SECTION OverlappedCtxLock;
	std::stack<void*> OverlappedCtxPool;
	CRITICAL_SECTION TCPSocketsLock;
	std::vector<SOCKET> FreeTCPSockets;
    CRITICAL_SECTION UDPSocketsLock;
    std::vector<SOCKET> FreeUDPSockets;
	CRITICAL_SECTION FreeBuffersLock;
	std::vector<char*> FreeBuffers;
	UINT OverlappedCtxCount;
	UINT TCPSocketsCount;
    UINT UDPSocketsCount;
	UINT FreeBuffersCount;
};

class _ThreadPool
{
public:
	_ThreadPool();
	~_ThreadPool();
	void AttachHandle(HANDLE h);
	static DWORD WINAPI PoolThreadProc(PVOID pParam);
private:
	HANDLE hIOCP;
	std::vector<HANDLE> Threads;
};

};